home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-03 / imb9102.zip / CMDPARSE.BAS < prev    next >
BASIC Source File  |  1991-02-18  |  20KB  |  609 lines

  1. ' *******************************************
  2. ' **                                       **
  3. ' **    "DOS Command Line Parse Engine"    **
  4. ' **        Version 0.99 - 12/20/90        **
  5. ' **                                       **
  6. ' *******************************************
  7.  
  8. ' This is a group of procedures that form a "parse engine" for
  9. ' DOS. The "parse engine" breaks COMMAND$ down into individual
  10. ' switches and checks the switch against a given list of legal
  11. ' switches and "switch aliases". If the switch is legal up to
  12. ' this point, it is checked further for correct syntax (i.e.
  13. ' legal parameters, etc.)
  14.  
  15. ' The general syntax that is accepted by the "parse engine" is:
  16. '
  17. '       PROGNAME [InputFileSpec [OutputFileSpec]] [Switches]
  18. '
  19. ' NOTE: PROGNAME stands for the name of the program being
  20. '       executed, which is NOT part of the data checked by
  21. '       the "parse engine".
  22.  
  23. ' $DYNAMIC
  24.  
  25. DEFINT A-Z
  26.  
  27. CONST FALSE = 0, TRUE = NOT FALSE
  28. CONST ValidSymbol$ = "/-#"   ' Set equivalent switch symbols
  29.  
  30. TYPE NumericParameterType
  31.   Minimum AS INTEGER
  32.   Maximum AS INTEGER
  33.   Default AS INTEGER
  34. END TYPE
  35.  
  36. DECLARE FUNCTION BaseFilename$ (Filespec$)
  37. DECLARE FUNCTION BTRIM$ (Argument$)
  38. DECLARE FUNCTION Extension$ (Filespec$)
  39. DECLARE FUNCTION FinishedFilespec$ (Filespec$, DefaultFilepec$)
  40. DECLARE FUNCTION NumericSwitchValue (SwitchNameToCheck$)
  41. DECLARE FUNCTION TextSwitchValue$ (SwitchNameToCheck$)
  42.  
  43. DECLARE SUB GetLegalSwitches ()
  44. DECLARE SUB ParseFilespecs (DefaultInputName$,DefaultOutputName$)
  45. DECLARE SUB ParseSwitches ()
  46.  
  47. DECLARE SUB RunParseEngine () ' Demonstrate the "parse engine"
  48.  
  49. ON ERROR GOTO Oops
  50.  
  51. OPTION BASE 1
  52.  
  53. 'BEGINNING OF SECTION 1 OF 3 FOR QBX 7.X USERS
  54. DIM SwitchName$(1), SwitchAlias$(1), SwitchType(1)
  55. DIM NumericParameter(1) AS NumericParameterType
  56. DIM SwitchValue(1), SwitchText$(1)
  57. 'END SECTION 1 OF 3 FOR QBX 7.X USERS
  58.  
  59. 'BEGINNING OF SECTION 1 OF 3 FOR QB 4.X USERS
  60. 'NbrParms = 8
  61. 'DIM SwitchName$(NbrParms), SwitchAlias$(NbrParms),
  62. 'DIM SwitchType(NbrParms)
  63. 'DIM NumericParameter(NbrParms) AS NumericParameterType
  64. 'DIM SwitchValue(NbrParms), SwitchText$(NbrParms)
  65. 'END OF SECTION 1 OF 3 FOR QB 4.X USERS
  66.  
  67. RunParseEngine
  68.  
  69. END
  70.  
  71.  
  72. LegalSwitchList:
  73.  
  74.   ' All the information regarding the switches (and their
  75.   ' aliases) is kept here. The first item of each line is
  76.   ' a legal switch name, followed by an alias name for that
  77.   ' switch. The next data item is an integer value that
  78.   ' classifies the type of data associated with the
  79.   ' corresponding switch. This value governs exactly what
  80.   ' subsequent data is expected to be read next. The format
  81.   ' of each line of data is as follows:
  82.     
  83.   '   DATA  SWITCH,ALIAS,0                 NO PARAMETERS ALLOWED
  84.   '   DATA  SWITCH,ALIAS,1,Min,Max,Default Opt # parm accepted
  85.   '   DATA  SWITCH,ALIAS,2                 Opt Text parm accepted
  86.   '   DATA  SWITCH,ALIAS,3,Min,Max,Default Opt Text OR # parm
  87.   '   DATA  SWITCH,ALIAS,-1,Min,Max        # parm REQUIRED
  88.   '   DATA  SWITCH,ALIAS,-2                Text parm REQUIRED
  89.   '   DATA  SWITCH,ALIAS,-3,Min,Max        Text OR # parm RQD
  90.     
  91.   ' NOTE: A local error handler is used to trap an "Out of data"
  92.   ' error, so the GetLegalSwitches procedure ends gracefully, and
  93.   ' no "sentinel" data is required here.
  94.  
  95.   DATA B,BATCH,0
  96.   DATA D,DECODE,-1,1,3
  97.   DATA E,ENCODE,1,0,2,0
  98.   DATA H,HELP,0
  99.   DATA L,LOCK,0
  100.   DATA S,SORT,2
  101.   DATA X,ERR,0
  102.   DATA ?,,0
  103.  
  104.  
  105. Oops:
  106.  
  107.   ' This is an error handler designed to trap the custom error
  108.   ' codes generated by the SUB ParseSwitches. The custom errors
  109.   ' are:
  110.  
  111.   '   Error Code  Condition
  112.   '   ==========  =========
  113.   '   200         Switch is illegal (not part of LegalSwitchList)
  114.   '   201         Missing required switch parameter
  115.   '   202         Switch has a parameter but should not have one
  116.   '   203         Numeric/Text mismatch
  117.   '   204         Illegal parameter quantity
  118.   '   205         Switch has been duplicated
  119.  
  120.   SELECT CASE ERR
  121.     CASE 200
  122.       PRINT "Unknown switch: "; BadSwitch$
  123.     CASE 201
  124.       PRINT "Missing parameter in switch: "; BadSwitch$
  125.     CASE 202
  126.       PRINT "Extraneous parameter in switch: "; BadSwitch$
  127.     CASE 203
  128.       PRINT "Parameter type mismatch in switch: "; BadSwitch$
  129.     CASE 204
  130.       PRINT "Illegal quantity in switch: "; BadSwitch$
  131.     CASE 205
  132.       PRINT "Duplicate switch: "; BadSwitch$
  133.     CASE ELSE
  134.       PRINT "BASIC run-time error #"; MID$(STR$(ERR), 2)
  135.   END SELECT
  136.  
  137. 'BEGINNING OF SECTION 2 OF 3 FOR QBX 7.X USERS
  138.   END ERR ' All errors are trapped, so RESUME is not necessary
  139. 'END OF SECTION 2 OF 3 FOR QBX 7.X USERS
  140.  
  141. 'BEGINNING OF SECTION 2 OF 3 FOR QB 4.X USERS
  142. '  END
  143. 'END OF SECTION 2 OF 3 FOR QB 4.X USERS
  144.  
  145. FUNCTION BaseFilename$ (Filespec$) STATIC
  146.  
  147.   ' This FUNCTION returns a truncated Filespec$, with the
  148.   ' extension cut off. If Filespec$ had a trailing period only
  149.   ' with no extension, the trailing period is not removed. This
  150.   ' will signal ParseFilespecs to not append a default file
  151.   ' extension onto Filespec$, when requested.
  152.     
  153.   Position = INSTR(Filespec$, ".")
  154.   SELECT CASE Position
  155.     CASE 0, LEN(Filespec$)
  156.       Build$ = Filespec$ ' leave "as is"...
  157.     CASE 1
  158.       Build$ = ""
  159.     CASE ELSE
  160.       Build$ = LEFT$(Build$, Position - 1)
  161.   END SELECT
  162.  
  163.   BaseFilename$ = Build$
  164.  
  165. END FUNCTION
  166.  
  167. REM $STATIC
  168. FUNCTION BTRIM$ (Argument$) STATIC
  169.  
  170.   BTRIM$ = RTRIM$(LTRIM$(Argument$)) ' BTRIM for "BOTH TRIM".
  171.  
  172. END FUNCTION
  173.  
  174. FUNCTION Extension$ (Filespec$) STATIC
  175.  
  176.   ' This FUNCTION returns only the FILE EXTENSION of a given
  177.   ' FileSpec, if one exists in the FileSpec parameter. Extensions
  178.   ' are parsed only where it is legal for them to be present.
  179.  
  180.   IF LEN(Filespec$) > 4 THEN
  181.     Position = INSTR(LEN(Filespec$) - 4, Filespec$, ".")
  182.   ELSE
  183.     Position = INSTR(Filespec$, ".")
  184.   END IF
  185.     
  186.   IF (Position > 0) AND (Position < LEN(Filespec$)) THEN
  187.     Extension$ = MID$(Filespec$, Position)
  188.   ELSE
  189.     Extension$ = ""
  190.   END IF
  191.  
  192. END FUNCTION
  193.  
  194. FUNCTION FinishedFilespec$ (Filespec$, DefaultFilespec$)
  195.  
  196.   ' This FUNCTION is used internally by ParseFilespecs to supply
  197.   ' any default filespec information not already supplied by
  198.   ' the user.
  199.  
  200.   IF LEN(BaseFilename$(Filespec$)) THEN
  201.     IF RIGHT$(Filespec$, 1) <> "." THEN
  202.       IF LEN(Extension$(Filespec$)) = 0 THEN _
  203.              Filespec$ = Filespec$ + Extension$(DefaultFilespec$)
  204.     END IF
  205.   ELSE
  206.     IF LEN(BaseFilename$(DefaultFilespec$)) THEN
  207.       Filespec$ = DefaultFilespec$
  208.     END IF
  209.   END IF
  210.  
  211.   FinishedFilespec$ = Filespec$
  212.  
  213. END FUNCTION
  214.  
  215. REM $DYNAMIC
  216. SUB GetLegalSwitches STATIC
  217.  
  218.   ' All of the information regarding the switches (and their
  219.   ' aliases) is read here, according to the data format
  220.   ' established in the main module (LegalSwitchList).
  221.  
  222.   SHARED SwitchName$(), SwitchAlias$(), SwitchType(), _
  223.          NumericParameter() AS NumericParameterType, _
  224.          SwitchValue(), SwitchText$()
  225.  
  226.  
  227.   RESTORE LegalSwitchList ' For use when other data is added.
  228.                           '   LegalSwitchList data MUST BE PLACED
  229.                           '   LAST, AFTER ALL OTHER DATA.
  230.  
  231. 'BEGINNING OF SECTION 3 OF 3 FOR QBX 7.X USERS
  232.  
  233.   ON LOCAL ERROR GOTO GLSerror
  234.  
  235.   DO
  236.     Index = Index + 1
  237.  
  238.     REDIM PRESERVE SwitchName$(Index), SwitchAlias$(Index)
  239.     REDIM PRESERVE SwitchType(Index)
  240.     REDIM PRESERVE NumericParameter(Index) AS NumericParameterType
  241.  
  242.     READ SwitchName$(Index),SwitchAlias$(Index),SwitchType(Index)
  243.     SELECT CASE SwitchType(Index)
  244.       CASE 0, 2, -2                    ' Nothing more to read...
  245.       CASE 1, 3
  246.         READ NumericParameter(Index).Minimum,_
  247.              NumericParameter(Index).Maximum,_
  248.              NumericParameter(Index).Default
  249.       CASE -1, -3
  250.         READ NumericParameter(Index).Minimum,_
  251.              NumericParameter(Index).Maximum
  252.       CASE ELSE
  253.         ERROR 2 ' Syntax error (illegal data)
  254.     END SELECT
  255.   LOOP WHILE LEN(SwitchName$(Index))
  256.  
  257.   IF Index > 1 THEN _
  258.     REDIM PRESERVE SwitchName$(Index - 1), _
  259.       SwitchAlias$(Index - 1),SwitchType(Index - 1), _
  260.       NumericParameter(Index - 1) AS NumericParameterType, _
  261.       SwitchValue(Index - 1), SwitchText$(Index - 1)
  262.   EXIT SUB
  263.  
  264. GLSerror: ' Intercepts "Out of data" error only
  265.  
  266.   IF ERR = 4 THEN RESUME NEXT ELSE ERROR ERR
  267.  
  268. 'END SECTION 3 OF 3 FOR QBX 7.X USERS
  269.  
  270. 'BEGINNING OF SECTION 3 OF 3 FOR QB 4.X USERS
  271.  
  272. '  FOR Index = 1 TO UBOUND(SwitchName$)
  273. '    READ SwitchName$(Index), SwitchAlias$(Index),_
  274. '         SwitchType(Index)
  275. '    SELECT CASE SwitchType(Index)
  276. '      CASE 0, 2, -2              ' Nothing more to read...
  277. '      CASE 1, 3
  278. '        READ NumericParameter(Index).Minimum,_
  279. '             NumericParameter(Index).Maximum,_
  280. '             NumericParameter(Index).Default
  281. '      CASE -1, -3
  282. '        READ NumericParameter(Index).Minimum,_
  283. '             NumericParameter(Index).Maximum
  284. '      CASE ELSE
  285. '        ERROR 2 ' Syntax error (illegal data)
  286. '    END SELECT
  287. '  NEXT Index
  288.  
  289. 'END OF SECTION 3 OF 3 FOR QB 4.X USERS
  290.  
  291. END SUB
  292.  
  293. FUNCTION NumericSwitchValue (SwitchNameToCheck$)
  294.  
  295.   ' This FUNCTION looks up the value of a given switch, by the
  296.   ' name of the switch. Of course, if no value was entered after
  297.   ' the switch name a zero will be returned. Other possible
  298.   ' values include &H8000 (if the switch was not found in
  299.   ' COMMAND$) and &H8001 (meaning that this is a "text switch").
  300.   ' Switch aliases are not allowed to be used to look up a value,
  301.   ' in order to keep the code compact. Use of a "switch symbol"
  302.   ' (/, etc.) before the name may be used, but is not required.
  303.  
  304.   SHARED SwitchName$(), SwitchValue()
  305.  
  306.   ' The next instruction makes the FUNCTION somewhat "forgiving"
  307.  
  308.   SwitchNameToCheck$ = BTRIM$(UCASE$(SwitchNameToCheck$))
  309.  
  310.   IF INSTR(ValidSymbol$, LEFT$(SwitchNameToCheck$, 1)) THEN _
  311.     SwitchNameToCheck$ = LTRIM$(MID$(SwitchNameToCheck$, 2))
  312.  
  313.   Index = 0
  314.   DO
  315.    Index = Index + 1
  316.   LOOP UNTIL (Index = UBOUND(SwitchName$)) OR _
  317.     (SwitchName$(Index) = SwitchNameToCheck$)
  318.  
  319.   IF SwitchName$(Index) = SwitchNameToCheck$ THEN
  320.     NumericSwitchValue = SwitchValue(Index)
  321.   ELSE
  322.     NumericSwitchValue = &H8000
  323.   END IF
  324.  
  325. END FUNCTION
  326.  
  327.  
  328. SUB ParseFilespecs (DefaultInputName$, DefaultOutputName$) STATIC
  329.  
  330.   ' This SUB builds input and output FileSpecs for use by other
  331.   ' procedures, using the supplied filenames if none were entered
  332.   ' from the DOS command line. Lone extensions may also be used
  333.   ' for DefaultInputName$ and DefaultOutputName$; this is used
  334.   ' to force a filename to be required, yet allowing a default
  335.   ' extension to be used.
  336.  
  337.   SHARED InputFilespec$, OutputFilespec$
  338.  
  339.   DefaultInputName$ = UCASE$(BTRIM$(DefaultInputName$))
  340.   DefaultOutputName$ = UCASE$(BTRIM$(DefaultOutputName$))
  341.  
  342.   IF INSTR(ValidSymbol$, LEFT$(COMMAND$, 1)) THEN
  343.     FileSpecParameters$ = ""
  344.   ELSE
  345.     FOR Index = 1 TO LEN(ValidSymbol$)
  346.       SymbolPosition = INSTR(COMMAND$,MID$(ValidSymbol$,Index,1))
  347.       IF SymbolPosition THEN _
  348.         IF (SymbolPosition < FirstSwitchPosition) OR _
  349.            (FirstSwitchPosition = 0) THEN _
  350.             FirstSwitchPosition = SymbolPosition
  351.     NEXT
  352.     IF FirstSwitchPosition THEN
  353.       FileSpecParameters$ = LEFT$(COMMAND$,FirstSwitchPosition-1)
  354.     ELSE
  355.       FileSpecParameters$ = COMMAND$
  356.     END IF
  357.   END IF
  358.  
  359.   InBuild$ = FinishedFilespec$(BTRIM$(LEFT$(FileSpecParameters$,_
  360.     INSTR(FileSpecParameters$ + " ", " "))), DefaultInputName$)
  361.   OutBuild$ = FinishedFilespec$(BTRIM$(MID$(FileSpecParameters$,_
  362.     LEN(InBuild$) + 1)), DefaultOutputName$)
  363.  
  364.   InputFilespec$ = InBuild$
  365.   OutputFilespec$ = OutBuild$
  366.  
  367. END SUB
  368.  
  369. SUB ParseSwitches STATIC
  370.  
  371.   ' This SUB parses COMMAND$, checks for proper switch syntax,
  372.   ' proper parameter types and values, and also ensures that a
  373.   ' switch is not duplicated. Custom errors may be generated, as
  374.   ' follows:
  375.  
  376.   '   Error Code      Condition
  377.   '   ==========      =========
  378.   '       200         Switch is illegal (not in LegalSwitchList)
  379.   '       201         Missing required switch parameter
  380.   '       202         Switch has a parameter but should not
  381.   '       203         Numeric/Text mismatch
  382.   '       204         Illegal parameter quantity
  383.   '       205         Switch has been duplicated
  384.  
  385.   ' Every switch will return a numeric value in the SwitchValue
  386.   ' array. Note that the value &H8000 is initially assigned to
  387.   ' each element to indicate that the switch wasn't found in
  388.   ' COMMAND$. This is used to during the parsing process to
  389.   ' determine if a switch is duplicated. Later, the application
  390.   ' can determine if the switch was ever found in COMMAND$.
  391.  
  392.   ' The value &H8001 is assigned to those switches that have
  393.   ' valid text data that should be read in the SwitchText$ array.
  394.  
  395.   SHARED SwitchName$(), SwitchAlias$(), SwitchType(), _
  396.          NumericParameter() AS NumericParameterType, _
  397.          SwitchValue(), SwitchText$()
  398.   SHARED BadSwitch$ ' Used to refer to current switch name in
  399.                     '   error trapping, should that be necessary
  400.  
  401.   FOR Index = 1 TO UBOUND(SwitchName$)
  402.       SwitchValue(Index) = &H8000
  403.   NEXT
  404.     
  405.   IF LEN(COMMAND$) AND _
  406.     NOT (INSTR(ValidSymbol$, RIGHT$(COMMAND$, 1)) > 0) THEN
  407.  
  408.     FOR Index = 1 TO LEN(ValidSymbol$)
  409.       SymbolPosition = INSTR(COMMAND$,MID$(ValidSymbol$,Index,1))
  410.       IF SymbolPosition THEN _
  411.          IF (SymbolPosition < Position) OR _
  412.             (Position = 0) THEN Position = SymbolPosition
  413.     NEXT
  414.         
  415.     DO
  416.       NextPosition = 0 ' FOR...NEXT loop sets NextPosition to _
  417.                        '   lowest SymbolPosition past current _
  418.                        '   value of Position
  419.  
  420.       FOR Index = 1 TO LEN(ValidSymbol$)
  421.         SymbolPosition = INSTR(Position + 1, COMMAND$, _
  422.                           MID$(ValidSymbol$, Index, 1))
  423.         IF SymbolPosition THEN _
  424.           IF (SymbolPosition < NextPosition) OR _
  425.              (NextPosition = 0) THEN NextPosition=SymbolPosition
  426.       NEXT
  427.  
  428.       IF NextPosition THEN
  429.         ParameterCheck$ = MID$(COMMAND$, Position + 1, _
  430.                           NextPosition - (Position + 1))
  431.       ELSE
  432.         ParameterCheck$ = MID$(COMMAND$, Position + 1)
  433.         NextPosition = LEN(COMMAND$)
  434.       END IF
  435.  
  436.       SwitchFound = FALSE
  437.       Index = 0
  438.       DO
  439.         Index = Index + 1
  440.         IF LEN(SwitchAlias$(Index)) THEN _
  441.           SwitchFound = (INSTR(ParameterCheck$, _
  442.           SwitchAlias$(Index)) = 1)
  443.       LOOP UNTIL (SwitchFound) OR Index = UBOUND(SwitchName$)
  444.  
  445.       BadSwitch$ = LEFT$(ValidSymbol$, 1) + SwitchName$(Index)
  446.  
  447.       IF SwitchFound THEN
  448.         IF SwitchValue(Index) = &H8000 THEN
  449.           Position = Position + LEN(SwitchAlias$(Index)) + 1
  450.           SwitchValue(Index) = 0
  451.         ELSE
  452.           ERROR 205 ' Duplicate switch
  453.         END IF
  454.       ELSE
  455.         Index = 0
  456.         DO
  457.           Index = Index + 1
  458.           SwitchFound = (INSTR(ParameterCheck$, _
  459.                          SwitchName$(Index)) = 1)
  460.         LOOP UNTIL (SwitchFound) OR Index = UBOUND(SwitchName$)
  461.  
  462.         BadSwitch$ = LEFT$(ValidSymbol$, 1) + SwitchName$(Index)
  463.  
  464.         IF SwitchFound THEN
  465.           IF SwitchValue(Index) = &H8000 THEN
  466.             Position = Position + LEN(SwitchName$(Index)) + 1
  467.             SwitchValue(Index) = 0
  468.           ELSE
  469.             ERROR 205 ' Duplicate switch
  470.           END IF
  471.         ELSE
  472.           BadSwitch$ = LEFT$(ValidSymbol$, 1) + ParameterCheck$
  473.           IF INSTR(BadSwitch$, ":") > 2 THEN _
  474.             BadSwitch$ = _
  475.               LEFT$(BadSwitch$, INSTR(BadSwitch$, ":") - 1)
  476.           ERROR 200 ' Illegal switch
  477.         END IF
  478.       END IF
  479.  
  480.       IF SwitchFound THEN
  481.         IF (MID$(COMMAND$, Position, 1) = ":") AND _
  482.            (Position < LEN(COMMAND$)) THEN Position = Position+1
  483.         IF NextPosition < LEN(COMMAND$) THEN
  484.           ParameterCheck$ = BTRIM$(MID$(COMMAND$, Position, _
  485.                                         NextPosition - Position))
  486.         ELSE
  487.           ParameterCheck$ = LTRIM$(MID$(COMMAND$, Position))
  488.         END IF
  489.  
  490.         IF LEN(ParameterCheck$) THEN
  491.           IF SwitchType(Index) = 0 THEN
  492.             ERROR 202 ' Parameter not allowed!
  493.           ELSE
  494.             IF INSTR("0123456789",LEFT$(ParameterCheck$, 1)) THEN
  495.                 IF ABS(SwitchType(Index)) = 2 THEN
  496.                     ERROR 203 ' Switch parameter type mismatch
  497.                 ELSE
  498.                     SwitchValue(Index) = VAL(ParameterCheck$)
  499.                     IF (SwitchValue(Index) < _
  500.                         NumericParameter(Index).Minimum) OR _
  501.                         (SwitchValue(Index) > _
  502.                         NumericParameter(Index).Maximum) THEN _
  503.                           ERROR 204  ' Illegal quantity
  504.                 END IF
  505.             ELSE
  506.                 IF ABS(SwitchType(Index)) = 1 THEN
  507.                     ERROR 203 ' Switch parameter type mismatch
  508.                 ELSE
  509.                     SwitchText$(Index) = ParameterCheck$
  510.      ' Indicates that there is valid text in SwitchText$(Index)..
  511.                     SwitchValue(Index) = &H8001 
  512.                 END IF
  513.             END IF
  514.           END IF
  515.         ELSE
  516.           IF SwitchType(Index) < 0 THEN
  517.             ERROR 201                       ' Parameter required!
  518.           ELSEIF SwitchType(Index) = 2 THEN
  519. ' Indicates that the value of SwitchText$(Index) is the null text
  520.             SwitchValue(Index) = &H8001 
  521.           ELSE
  522.             SwitchValue(Index) = NumericParameter(Index).Default
  523.           END IF
  524.         END IF
  525.       END IF
  526.  
  527.       Position = NextPosition
  528.     LOOP UNTIL Position = LEN(COMMAND$)
  529.   END IF
  530.  
  531. END SUB
  532.  
  533. SUB RunParseEngine STATIC
  534.  
  535.   ' This SUB demonstrates how the components of the "Parse
  536.   ' Engine" work together.
  537.  
  538.   SHARED SwitchName$(), SwitchAlias$(), SwitchType()
  539.   SHARED NumericParameter() AS NumericParameterType,SwitchText$()
  540.   SHARED SwitchTextData$ ' For use only if SwitchVal
  541.                          '   returns a value of &H8006
  542.   SHARED InputFilespec$, OutputFilespec$
  543.  
  544.   Q$ = CHR$(34)
  545.  
  546.   PRINT
  547.   PRINT "CMDPARSE - DOS Command Line "; q$; "Parse Engine"; q$
  548.   PRINT "Copyright (c)1991 Barry L. Camp - All Rights Reserved"
  549.   PRINT
  550.   PRINT "COMMAND$   : "; q$; COMMAND$; q$
  551.   GetLegalSwitches
  552.   ParseFilespecs "TESTFILE.IN", "TESTFILE.OUT"
  553.   PRINT "Input File : "; q$; InputFilespec$; q$
  554.   PRINT "Output File: "; q$; OutputFilespec$; q$
  555.   PRINT
  556.   ParseSwitches
  557.   IF LEN(SwitchName$(1)) THEN
  558.     FOR Index = 1 TO UBOUND(SwitchName$)
  559.       PRINT "Value of "; q$; LEFT$(ValidSymbol$, 1); _
  560.              SwitchName$(Index); q$; " is ";
  561.       Value = NumericSwitchValue(SwitchName$(Index)) ' BYVAL
  562.       SELECT CASE Value
  563.         CASE &H8000
  564.           PRINT "undefined (switch not found in COMMAND$)"
  565.         CASE &H8001
  566.           PRINT q$; SwitchText$(Index); q$
  567.         CASE ELSE
  568.           PRINT MID$(STR$(Value), 2)
  569.       END SELECT
  570.     NEXT
  571.   ELSE
  572.     PRINT "No legal switches were defined."
  573.   END IF
  574.  
  575. END SUB
  576.  
  577. FUNCTION TextSwitchValue$ (SwitchNameToCheck$) STATIC
  578.  
  579.   ' This FUNCTION looks up the "text value" of a given switch, by
  580.   ' the name of the switch. "Text value" means the text of the
  581.   ' non-numeric parameter following the switch name (and the
  582.   ' optional colon). Of course, if no text was entered after the
  583.   ' switch name (or this is not a "text switch"), then a null
  584.   ' string is returned. Switch aliases are not allowed to be used
  585.   ' to look up a text value, in order to keep the code compact.
  586.   ' Use of a "switch symbol" (/, etc.) before the name may be
  587.   ' used, but is not required.
  588.  
  589.   SHARED SwitchName$(), SwitchText$()
  590.  
  591.   ' this makes the FUNCTION somewhat "forgiving"...
  592.   SwitchNameToCheck$ = BTRIM$(UCASE$(SwitchNameToCheck$)) 
  593.   IF INSTR(ValidSymbol$, LEFT$(SwitchNameToCheck$, 1)) THEN _
  594.     SwitchNameToCheck$ = LTRIM$(MID$(SwitchNameToCheck$, 2))
  595.  
  596.   Index = 0
  597.   DO
  598.      Index = Index + 1
  599.   LOOP UNTIL (Index = UBOUND(SwitchName$)) OR _
  600.              (SwitchName$(Index) = SwitchNameToCheck$)
  601.  
  602.   IF SwitchName$(Index) = SwitchNameToCheck$ THEN
  603.       TextSwitchValue$ = SwitchText$(Index)
  604.   ELSE
  605.       TextSwitchValue$ = ""
  606.   END IF
  607.  
  608. END FUNCTION
  609.